package com.aiwu.utils

import android.content.Context
import android.preference.PreferenceManager
import com.aiwu.bean.ScreenConfig
import com.aiwu.library.App
import org.citra.citra_emu.display.ScreenLayout
import org.citra.citra_emu.utils.EmulationMenuSettings
import org.citra.citra_emu.utils.GameHelper

class PrefsHelper private constructor() {
    companion object {
        private const val FONT = "isAcgFont"
        private const val INIT_DEFAULT_FONT = "initDefaultFont"

        //region屏幕布局相关
        //横屏id
        const val SCREEN_CONFIG_ID_LANDSCAPE_START = 11
        const val SCREEN_CONFIG_ID_LANDSCAPE_END = 20

        //竖屏id
        const val SCREEN_CONFIG_ID_PORTRAIT_START = 100
        const val SCREEN_CONFIG_ID_PORTRAIT_END = 110
        private const val SCREEN_CONFIG_PREFIX = "screen_config_"
        private const val LAST_SCREEN_CONFIG = "last_screen_config"
        private const val LAST_LANDSCAPE_SCREEN_CONFIG = "last_landscape_screen_config"
        private const val LAST_PORTRAIT_SCREEN_CONFIG = "last_portrait_screen_config"
        private const val KEY_NAME = "name"
        private const val KEY_TOP_LEFT = "topLeft"
        private const val KEY_TOP_TOP = "topTop"
        private const val KEY_TOP_RIGHT = "topRight"
        private const val KEY_TOP_BOTTOM = "topBottom"
        private const val KEY_BOTTOM_LEFT = "bottomLeft"
        private const val KEY_BOTTOM_TOP = "bottomTop"
        private const val KEY_BOTTOM_RIGHT = "bottomRight"
        private const val KEY_BOTTOM_BOTTOM = "bottomBottom"


        private const val FLOATING_BOTTOM_SCREEN_LOCATION = "floating_bottom_screen_location"
        private const val FLOATING_SCREEN_LAYOUT_LOCATION = "floating_screen_layout_location"
        private const val FLOATING_CHAT_LAYOUT_LOCATION = "floating_chat_layout_location"
        private const val QUICK_SCREEN_LAYOUT = "quick_screen_layout"
        private const val QUICK_SWITCH_BOTTOM_SCREEN = "quick_switch_bottom_screen"

        private const val NET_PLAY_USERNAME = "NetPlayUsername"
        private const val NET_PLAY_ROOM_ADDRESS = "NetPlayRoomAddress"
        private const val NET_PLAY_ROOM_PORT = "NetPlayRoomPort"

        private const val KEY_ALL_GAME_PATH = "all_game_path"

        //endregion
        @JvmStatic
        val instance: PrefsHelper by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
            PrefsHelper()
        }
    }

    private val defaultSharedPreferences by lazy {
        PreferenceManager.getDefaultSharedPreferences(App.getContext())
    }
    private val defaultEditor by lazy {
        defaultSharedPreferences.edit()
    }

    //是否设置了默认字体
    fun isInitDefaultFont(): Boolean {
        return defaultSharedPreferences.getBoolean(INIT_DEFAULT_FONT, false)
    }

    fun setInitDefaultFont(initDefaultFont: Boolean) {
        defaultEditor.putBoolean(INIT_DEFAULT_FONT, initDefaultFont).apply()
    }

    //是否acg字体
    fun isAcgFont(): Boolean {
        return defaultSharedPreferences.getBoolean(FONT, false)
    }

    fun setAcgFont(acgFont: Boolean) {
        defaultEditor.putBoolean(FONT, acgFont).apply()
    }


    //region屏幕布局相关

    //endregion
    //region屏幕布局相关
    /**
     * 获取上次的屏幕配置
     */
    fun getLastScreenConfigId(): Int {
        return defaultSharedPreferences.getInt(
            LAST_SCREEN_CONFIG,
            EmulationMenuSettings.landscapeScreenLayout
        )
    }

    fun setLastScreenConfigId(id: Int) {
        defaultEditor.putInt(LAST_SCREEN_CONFIG, id).apply()
    }

    fun getLastLandscapeScreenConfigId(): Int {
        return defaultSharedPreferences.getInt(
            LAST_LANDSCAPE_SCREEN_CONFIG,
            EmulationMenuSettings.landscapeScreenLayout
        )
    }

    fun setLastLandscapeScreenConfigId(id: Int) {
        defaultEditor.putInt(LAST_LANDSCAPE_SCREEN_CONFIG, id).apply()
    }

    fun getLastPortraitScreenConfigId(): Int {
        return defaultSharedPreferences.getInt(
            LAST_PORTRAIT_SCREEN_CONFIG,
            ScreenLayout.DEFAULT.int
        )
    }

    fun setLastPortraitScreenConfigId(id: Int) {
        defaultEditor.putInt(LAST_PORTRAIT_SCREEN_CONFIG, id).apply()
    }

    private fun getScreenConfigSp(id: Int) =
        App.getContext().getSharedPreferences(SCREEN_CONFIG_PREFIX + id, Context.MODE_PRIVATE)

    fun getScreenConfig(id: Int): ScreenConfig? {
        val pref = getScreenConfigSp(id)
        val map = pref.all as? Map<String, String>
        if (map.isNullOrEmpty()) {
            return null
        }
        return ScreenConfig(
            true,
            id == getLastScreenConfigId(),
            id,
            map.getOrDefault(KEY_NAME, ""),
            getOrDefault(map, KEY_TOP_LEFT),
            getOrDefault(map, KEY_TOP_TOP),
            getOrDefault(map, KEY_TOP_RIGHT),
            getOrDefault(map, KEY_TOP_BOTTOM),
            getOrDefault(map, KEY_BOTTOM_LEFT),
            getOrDefault(map, KEY_BOTTOM_TOP),
            getOrDefault(map, KEY_BOTTOM_RIGHT),
            getOrDefault(map, KEY_BOTTOM_BOTTOM)
        )
    }

    private fun getOrDefault(map: Map<String, String>, key: String): Int {
        val v = map[key]
        return if (v.isNullOrEmpty()) {
            0
        } else v.toInt()
    }

    fun saveNewScreenConfig(
        id: Int,
        name: String,
        topLeft: Int,
        topTop: Int,
        topRight: Int,
        topBottom: Int,
        bottomLeft: Int,
        bottomTop: Int,
        bottomRight: Int,
        bottomBottom: Int
    ) {
        getScreenConfigSp(id)
            .edit()
            .clear()
            .putString(KEY_NAME, name)
            .putString(KEY_TOP_LEFT, topLeft.toString())
            .putString(KEY_TOP_TOP, topTop.toString())
            .putString(KEY_TOP_RIGHT, topRight.toString())
            .putString(KEY_TOP_BOTTOM, topBottom.toString())
            .putString(KEY_BOTTOM_LEFT, bottomLeft.toString())
            .putString(KEY_BOTTOM_TOP, bottomTop.toString())
            .putString(KEY_BOTTOM_RIGHT, bottomRight.toString())
            .putString(KEY_BOTTOM_BOTTOM, bottomBottom.toString())
            .apply()
    }

    fun editScreenConfigValue(
        id: Int,
        topLeft: Int,
        topTop: Int,
        topRight: Int,
        topBottom: Int,
        bottomLeft: Int,
        bottomTop: Int,
        bottomRight: Int,
        bottomBottom: Int
    ) {
        getScreenConfigSp(id)
            .edit()
            .putString(KEY_TOP_LEFT, topLeft.toString())
            .putString(KEY_TOP_TOP, topTop.toString())
            .putString(KEY_TOP_RIGHT, topRight.toString())
            .putString(KEY_TOP_BOTTOM, topBottom.toString())
            .putString(KEY_BOTTOM_LEFT, bottomLeft.toString())
            .putString(KEY_BOTTOM_TOP, bottomTop.toString())
            .putString(KEY_BOTTOM_RIGHT, bottomRight.toString())
            .putString(KEY_BOTTOM_BOTTOM, bottomBottom.toString())
            .apply()
    }

    fun editScreenConfigName(id: Int, newName: String) {
        getScreenConfigSp(id)
            .edit()
            .putString(KEY_NAME, newName)
            .apply()
    }

    fun removeScreenConfig(id: Int) {
        getScreenConfigSp(id)
            .edit()
            .clear()
            .apply()
    }
    //endregion

    //region悬浮位置
    fun setFloatingBottomScreenLocation(x: Int, y: Int) {
        defaultEditor.putString(FLOATING_BOTTOM_SCREEN_LOCATION, x.toString() + "_" + y).apply()
    }

    fun getFloatingBottomScreenLocation(): IntArray? {
        try {
            val str =
                defaultSharedPreferences.getString(FLOATING_BOTTOM_SCREEN_LOCATION, null)
                    ?: return null
            val lc = str.split("_")
            return intArrayOf(lc[0].toInt(), lc[1].toInt())
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return null
    }

    fun removeFloatingBottomScreenLocation() {
        defaultEditor.remove(FLOATING_BOTTOM_SCREEN_LOCATION).apply()
    }

    fun setFloatingScreenLayoutLocation(x: Int, y: Int) {
        defaultEditor.putString(FLOATING_SCREEN_LAYOUT_LOCATION, x.toString() + "_" + y).apply()
    }

    fun getFloatingScreenLayoutLocation(): IntArray? {
        try {
            val str = defaultSharedPreferences.getString(FLOATING_SCREEN_LAYOUT_LOCATION, null)
                ?: return null
            val lc = str.split("_")
            return intArrayOf(lc[0].toInt(), lc[1].toInt())
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return null
    }

    /**
     * 重置
     */
    fun resetFloatingScreenLayout() {
        defaultEditor.remove(FLOATING_SCREEN_LAYOUT_LOCATION)
            .remove(QUICK_SCREEN_LAYOUT)
            .apply()
    }

    fun setFloatingChatLocation(x: Int, y: Int) {
        defaultEditor.putString(FLOATING_CHAT_LAYOUT_LOCATION, x.toString() + "_" + y).apply()
    }

    fun getFloatingChatLocation(): IntArray? {
        try {
            val str = defaultSharedPreferences.getString(FLOATING_CHAT_LAYOUT_LOCATION, null)
                ?: return null
            val lc = str.split("_")
            return intArrayOf(lc[0].toInt(), lc[1].toInt())
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return null
    }

    fun removeFloatingChatLocation() {
        defaultEditor.remove(FLOATING_CHAT_LAYOUT_LOCATION).apply()
    }
    //endregion

    //endregion
    //region 快捷切换屏幕布局
    fun setQuickScreenLayout(layout1: Int, layout2: Int) {
        defaultEditor.putString(QUICK_SCREEN_LAYOUT, layout1.toString() + "_" + layout2).apply()
    }

    fun isQuickScreenLayout(): Boolean {
        return getQuickScreenLayout() != null
    }

    fun getQuickScreenLayout(): IntArray? {
        try {
            val str = defaultSharedPreferences.getString(QUICK_SCREEN_LAYOUT, null)
                ?: return null
            val lc = str.split("_")
            return intArrayOf(lc[0].toInt(), lc[1].toInt())
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return null
    }

    fun removeQuickScreenLayout() {
        defaultEditor.remove(QUICK_SCREEN_LAYOUT).apply()
    }

    //endregion
    //是否开启快速切换副屏幕
    fun isQuickSwitchBottomScreen(): Boolean {
        return defaultSharedPreferences.getBoolean(QUICK_SWITCH_BOTTOM_SCREEN, true)
    }

    fun setQuickSwitchBottomScreen(enable: Boolean) {
        defaultEditor.putBoolean(QUICK_SWITCH_BOTTOM_SCREEN, enable).apply()
    }

    //region 对战
    fun getNetPlayUsername(defValue: String): String {
        return defaultSharedPreferences.getString(NET_PLAY_USERNAME, defValue)!!
    }

    fun setNetPlayUsername(name: String) {
        defaultEditor.putString(NET_PLAY_USERNAME, name).apply()
    }

    fun getRoomAddress(defValue: String): String {
        return defaultSharedPreferences.getString(NET_PLAY_ROOM_ADDRESS, defValue)!!
    }

    fun setRoomAddress(address: String) {
        defaultEditor.putString(NET_PLAY_ROOM_ADDRESS, address).apply()
    }

    fun getRoomPort(defValue: String): String {
        return defaultSharedPreferences.getString(NET_PLAY_ROOM_PORT, defValue)!!
    }

    fun setRoomPort(port: String) {
        defaultEditor.putString(NET_PLAY_ROOM_PORT, port).apply()
    }

    //endregion
    fun getLastGameDirectory(defValue: String? = ""): String? {
        return defaultSharedPreferences.getString(GameHelper.KEY_GAME_PATH, defValue)
    }

    /**
     * 添加游戏文件夹
     * @param replaceLastGameDir 是否替换最近的游戏文件夹
     */
    fun addGameDirectory(uriString: String, replaceLastGameDir: Boolean) {
        val lastGameDirector = getLastGameDirectory(null)
        if (replaceLastGameDir || lastGameDirector == null) {
            defaultEditor.putString(GameHelper.KEY_GAME_PATH, uriString).apply()
        }
        var allGameDirectorySet =
            defaultSharedPreferences.getStringSet(KEY_ALL_GAME_PATH, null)?.toHashSet()
        if (allGameDirectorySet == null || !allGameDirectorySet.contains(uriString)) {
            if (allGameDirectorySet == null) {
                allGameDirectorySet = HashSet()
            }
            allGameDirectorySet.add(uriString)
            defaultEditor.putStringSet(KEY_ALL_GAME_PATH, allGameDirectorySet).apply()
        }
    }

    /**
     * 获取所有游戏文件夹
     */
    fun getAllGameDirectory(): Set<String> {
        val resultSet =
            defaultSharedPreferences.getStringSet(KEY_ALL_GAME_PATH, null)?.toHashSet()
                ?: HashSet<String>()
        getLastGameDirectory(null)?.let {
            resultSet.add(it)
        }
        return resultSet
    }

    /**
     * 重置设置
     */
    fun resetSettings() {
        defaultEditor.remove(INIT_DEFAULT_FONT)
            .remove(LAST_SCREEN_CONFIG)
            .remove(LAST_LANDSCAPE_SCREEN_CONFIG)
            .remove(LAST_PORTRAIT_SCREEN_CONFIG)
            .remove(FLOATING_BOTTOM_SCREEN_LOCATION)
            .remove(FLOATING_SCREEN_LAYOUT_LOCATION)
            .remove(QUICK_SCREEN_LAYOUT)
            .remove(FLOATING_CHAT_LAYOUT_LOCATION)
            .remove(QUICK_SWITCH_BOTTOM_SCREEN)
            .remove(NET_PLAY_USERNAME)
            .remove(NET_PLAY_ROOM_ADDRESS)
            .remove(NET_PLAY_ROOM_PORT)
            .remove(GameHelper.KEY_GAME_PATH)
            .remove(KEY_ALL_GAME_PATH)
            .apply()
    }
}
